package com.dftdla.server.session;

import com.dftdla.dao.service.ChatUserService;
import com.dftdla.utils.ChannelUtils;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 14501
 */
@Slf4j
@Service
public class SessionMemoryImpl implements Session {

    private final Map<Long, Channel> usernameChannelMap = new ConcurrentHashMap<>();
    private final Map<Channel, Long> channelUserIdMap = new ConcurrentHashMap<>();
    private final Map<Channel,Map<String,Object>> channelAttributesMap = new ConcurrentHashMap<>();

    @Resource
    private ChatUserService chatUserService;

    @Override
    public Long getUserId(Channel channel) {
        return channelUserIdMap.get(channel);
    }

    @Override
    public String bind(Channel channel, Long userId) {
        usernameChannelMap.put(userId, channel);
        channelUserIdMap.put(channel, userId);
        channelAttributesMap.put(channel, new ConcurrentHashMap<>());
        return chatUserService.login(userId);
    }

    @Override
    public void unbind(Channel channel) {
        try {
            Long userId = channelUserIdMap.remove(channel);
            usernameChannelMap.remove(userId);
            channelAttributesMap.remove(channel);
            chatUserService.logout(userId);
            ChannelUtils.close(channel);
        }catch (Exception e) {
            log.error("不存在的channel");
        }
    }

    @Override
    public Object getAttribute(Channel channel, String name) {
        return channelAttributesMap.get(channel).get(name);
    }

    @Override
    public void setAttribute(Channel channel, String name, Object value) {
        channelAttributesMap.get(channel).put(name, value);
    }

    @Override
    public Channel getChannel(Long userId) {
        return usernameChannelMap.get(userId);
    }

    @Override
    public Integer listMsg(Object msg) {
        Integer count = 0;
        for(Map.Entry< Long,Channel> entry: usernameChannelMap.entrySet()){
            try {
                entry.getValue().writeAndFlush(new TextWebSocketFrame((String) msg));
                count ++;
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        return count;
    }

    @Override
    public String toString() {
        return usernameChannelMap.toString();
    }
}
